package com.vic.Builder;

import com.vic.Utils.StringUtils;
import com.vic.Utils.dateUtils;
import com.vic.bean.constant;
import com.vic.bean.fieldInfo;
import com.vic.bean.tableInfo;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.*;

/**
 * @Author: Vic Ly
 */
public class builderPo {
    private static final Logger log = LoggerFactory.getLogger(builderPo.class);
    public static void execute(tableInfo tableInfo){
        File folder = new File(constant.PATH_PO);
        if(!folder.exists()){
            folder.mkdirs();
        }
        File poFile = new File(folder,tableInfo.getBeanName() + ".java");
        // 接下来对生成的文件写入内容
        OutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(poFile);
            osw = new OutputStreamWriter(out,"utf8");
            bw = new BufferedWriter(osw);

            // bw.write("package com.vic.entity;");
            bw.write("package "+constant.PACKAGE_PO+";");
            bw.newLine();

            bw.write("import java.io.Serializable;");
            bw.newLine();
            bw.newLine();
            if(tableInfo.getHaveDateTime()|| tableInfo.getHaveDate()){
                bw.write("import java.util.Date;");
                bw.newLine();
                bw.write(constant.BEAN_DATE_FORMAT_CLASS+";");
                bw.newLine();
                bw.write(constant.BEAN_DATE_UnFORMAT_CLASS+";");
                bw.newLine();

                bw.write("import " + constant.ENUMS_PACKAGE + ".DateTimePatternEnum;");
                bw.newLine();
                bw.write("import " + constant.UTILS_PACKAGE + ".DateUtils;");
                bw.newLine();
            }
            // 忽略属性导包
            Boolean haveIgnoreBean = false;
            for (fieldInfo field:tableInfo.getFieldList()){
                if(ArrayUtils.contains(constant.IGNORE_BEAN_ToJSON_FIELD.split(","),field.getPropertyName())){
                    haveIgnoreBean = true;
                    break;
                    // 判断是否有属性需要忽略，如果有才导包
                }
            }
            if(haveIgnoreBean){
                bw.write(constant.IGNORE_BEAN_ToJSON_CLASS + ";");
                bw.newLine();
            }
            builderComment.addCommentByClass(bw,tableInfo.getComment());
            bw.newLine();
            bw.write("public class "+tableInfo.getBeanName() + " implements Serializable {");
            bw.newLine();
            // 属性
            for (fieldInfo field:tableInfo.getFieldList()){
                builderComment.addCommentByField(bw,field.getComment());
                // 日期+时间
                if(ArrayUtils.contains(constant.SQL_DATE_TIME,field.getSqlType())){
                    // 序列化注解
                    bw.write("\t"+String.format(constant.BEAN_DATE_FORMAT_EXPRESSION, dateUtils.Y_M_D_H_M_S));
                    bw.newLine();

                    // 反序列化注解
                    bw.write("\t"+String.format(constant.BEAN_DATE_UnFORMAT_EXPRESSION, dateUtils.Y_M_D_H_M_S));
                    bw.newLine();
                }
                // 日期
                if(ArrayUtils.contains(constant.SQL_DATE,field.getSqlType())){
                    // 同理
                    bw.write("\t"+String.format(constant.BEAN_DATE_FORMAT_EXPRESSION, dateUtils.Y_M_D));
                    bw.newLine();

                    bw.write("\t"+String.format(constant.BEAN_DATE_UnFORMAT_EXPRESSION, dateUtils.Y_M_D));
                    bw.newLine();
                }
                // 忽略属性注解
                if(ArrayUtils.contains(constant.IGNORE_BEAN_ToJSON_FIELD.split(","),field.getPropertyName())){
                    bw.write("\t"+constant.IGNORE_BEAN_ToJSON_FIELD_EXPRESSION);
                    bw.newLine();
                }
                // 属性生成
                bw.write("\t"+constant.ACCESS_PRIVATE+" "+field.getJavaType()+" "+field.getPropertyName()+";");
                bw.newLine();
            }
            // set/get方法
            for (fieldInfo field:tableInfo.getFieldList()){
                // 通过观察set/get方法可以发现形如xxx set+属性名(首字母大写) + (){xxx}
                String tempField = StringUtils.upperCaseFirstLetter(field.getPropertyName());
                bw.newLine();
                bw.write("\tpublic void set"+tempField+"("+field.getJavaType()+" "+field.getPropertyName()+") {");
                bw.newLine();
                bw.write("\t\tthis."+field.getPropertyName()+" = "+field.getPropertyName()+";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();

                bw.write("\tpublic "+field.getJavaType()+" get"+tempField+"() {");
                bw.newLine();
                bw.write("\t\treturn "+field.getPropertyName()+";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
            }
            // toString()方法
            StringBuilder details = new StringBuilder();
            details.append("\"").append(tableInfo.getBeanName()).append("{").append("\" +");
            for (fieldInfo field:tableInfo.getFieldList()){
                String temp = field.getPropertyName();
//                if(ArrayUtils.contains(constant.SQL_DATE_TIME,field.getSqlType())){
//                    // 日期时间类型
//                   // temp = "DateUtils.format("+temp+", DateTimePatternEnum.YYYY_MM_DD_HH_MM_SS.getPattern())";
//                } else if (ArrayUtils.contains(constant.SQL_DATE,field.getSqlType())) {
//                    temp = "DateUtils.format("+temp+", DateTimePatternEnum.YYYY_MM_DD.getPattern())";
//                }
                details.append("\n")
                        .append("\t\t\t"+"\""+temp+ " = "+"\" + "+temp+"+\""+"  "+"\"")
                        .append(" +");
            }
            details.append("\n\t\t").append("\"}\";");
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("\tpublic String toString() {");
            bw.newLine();
            bw.write("\t\treturn "+details);
            bw.newLine();
            bw.write("\t}");
            bw.newLine();

            bw.write("}");
            bw.flush();

        }catch (Exception e){
            log.error("创建po文件失败",e);
        }finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(osw != null){
                try {
                    osw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
